1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.google.common.primitives;
18
19 import static com.google.common.base.Preconditions.checkArgument;
20 import static com.google.common.base.Preconditions.checkElementIndex;
21 import static com.google.common.base.Preconditions.checkNotNull;
22 import static com.google.common.base.Preconditions.checkPositionIndexes;
23
24 import com.google.common.annotations.Beta;
25 import com.google.common.annotations.GwtCompatible;
26 import com.google.common.base.Converter;
27
28 import java.io.Serializable;
29 import java.util.AbstractList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.Collections;
33 import java.util.Comparator;
34 import java.util.List;
35 import java.util.RandomAccess;
36
37
38
39
40
41
42
43
44
45
46
47
48 @GwtCompatible
49 public final class Longs {
50 private Longs() {}
51
52
53
54
55
56 public static final int BYTES = Long.SIZE / Byte.SIZE;
57
58
59
60
61
62
63 public static final long MAX_POWER_OF_TWO = 1L << (Long.SIZE - 2);
64
65
66
67
68
69
70
71
72
73
74
75
76
77 public static int hashCode(long value) {
78 return (int) (value ^ (value >>> 32));
79 }
80
81
82
83
84
85
86
87
88
89
90
91
92
93 public static int compare(long a, long b) {
94 return (a < b) ? -1 : ((a > b) ? 1 : 0);
95 }
96
97
98
99
100
101
102
103
104
105
106 public static boolean contains(long[] array, long target) {
107 for (long value : array) {
108 if (value == target) {
109 return true;
110 }
111 }
112 return false;
113 }
114
115
116
117
118
119
120
121
122
123
124 public static int indexOf(long[] array, long target) {
125 return indexOf(array, target, 0, array.length);
126 }
127
128
129 private static int indexOf(
130 long[] array, long target, int start, int end) {
131 for (int i = start; i < end; i++) {
132 if (array[i] == target) {
133 return i;
134 }
135 }
136 return -1;
137 }
138
139
140
141
142
143
144
145
146
147
148
149
150 public static int indexOf(long[] array, long[] target) {
151 checkNotNull(array, "array");
152 checkNotNull(target, "target");
153 if (target.length == 0) {
154 return 0;
155 }
156
157 outer:
158 for (int i = 0; i < array.length - target.length + 1; i++) {
159 for (int j = 0; j < target.length; j++) {
160 if (array[i + j] != target[j]) {
161 continue outer;
162 }
163 }
164 return i;
165 }
166 return -1;
167 }
168
169
170
171
172
173
174
175
176
177
178 public static int lastIndexOf(long[] array, long target) {
179 return lastIndexOf(array, target, 0, array.length);
180 }
181
182
183 private static int lastIndexOf(
184 long[] array, long target, int start, int end) {
185 for (int i = end - 1; i >= start; i--) {
186 if (array[i] == target) {
187 return i;
188 }
189 }
190 return -1;
191 }
192
193
194
195
196
197
198
199
200
201 public static long min(long... array) {
202 checkArgument(array.length > 0);
203 long min = array[0];
204 for (int i = 1; i < array.length; i++) {
205 if (array[i] < min) {
206 min = array[i];
207 }
208 }
209 return min;
210 }
211
212
213
214
215
216
217
218
219
220 public static long max(long... array) {
221 checkArgument(array.length > 0);
222 long max = array[0];
223 for (int i = 1; i < array.length; i++) {
224 if (array[i] > max) {
225 max = array[i];
226 }
227 }
228 return max;
229 }
230
231
232
233
234
235
236
237
238
239
240 public static long[] concat(long[]... arrays) {
241 int length = 0;
242 for (long[] array : arrays) {
243 length += array.length;
244 }
245 long[] result = new long[length];
246 int pos = 0;
247 for (long[] array : arrays) {
248 System.arraycopy(array, 0, result, pos, array.length);
249 pos += array.length;
250 }
251 return result;
252 }
253
254
255
256
257
258
259
260
261
262
263
264
265 public static byte[] toByteArray(long value) {
266
267
268 byte[] result = new byte[8];
269 for (int i = 7; i >= 0; i--) {
270 result[i] = (byte) (value & 0xffL);
271 value >>= 8;
272 }
273 return result;
274 }
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289 public static long fromByteArray(byte[] bytes) {
290 checkArgument(bytes.length >= BYTES,
291 "array too small: %s < %s", bytes.length, BYTES);
292 return fromBytes(bytes[0], bytes[1], bytes[2], bytes[3],
293 bytes[4], bytes[5], bytes[6], bytes[7]) ;
294 }
295
296
297
298
299
300
301
302
303 public static long fromBytes(byte b1, byte b2, byte b3, byte b4,
304 byte b5, byte b6, byte b7, byte b8) {
305 return (b1 & 0xFFL) << 56
306 | (b2 & 0xFFL) << 48
307 | (b3 & 0xFFL) << 40
308 | (b4 & 0xFFL) << 32
309 | (b5 & 0xFFL) << 24
310 | (b6 & 0xFFL) << 16
311 | (b7 & 0xFFL) << 8
312 | (b8 & 0xFFL);
313 }
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335 @Beta
336 public static Long tryParse(String string) {
337 if (checkNotNull(string).isEmpty()) {
338 return null;
339 }
340 boolean negative = string.charAt(0) == '-';
341 int index = negative ? 1 : 0;
342 if (index == string.length()) {
343 return null;
344 }
345 int digit = string.charAt(index++) - '0';
346 if (digit < 0 || digit > 9) {
347 return null;
348 }
349 long accum = -digit;
350 while (index < string.length()) {
351 digit = string.charAt(index++) - '0';
352 if (digit < 0 || digit > 9 || accum < Long.MIN_VALUE / 10) {
353 return null;
354 }
355 accum *= 10;
356 if (accum < Long.MIN_VALUE + digit) {
357 return null;
358 }
359 accum -= digit;
360 }
361
362 if (negative) {
363 return accum;
364 } else if (accum == Long.MIN_VALUE) {
365 return null;
366 } else {
367 return -accum;
368 }
369 }
370
371 private static final class LongConverter extends Converter<String, Long> implements Serializable {
372 static final LongConverter INSTANCE = new LongConverter();
373
374 @Override
375 protected Long doForward(String value) {
376 return Long.decode(value);
377 }
378
379 @Override
380 protected String doBackward(Long value) {
381 return value.toString();
382 }
383
384 @Override
385 public String toString() {
386 return "Longs.stringConverter()";
387 }
388
389 private Object readResolve() {
390 return INSTANCE;
391 }
392 private static final long serialVersionUID = 1;
393 }
394
395
396
397
398
399
400
401 @Beta
402 public static Converter<String, Long> stringConverter() {
403 return LongConverter.INSTANCE;
404 }
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422 public static long[] ensureCapacity(
423 long[] array, int minLength, int padding) {
424 checkArgument(minLength >= 0, "Invalid minLength: %s", minLength);
425 checkArgument(padding >= 0, "Invalid padding: %s", padding);
426 return (array.length < minLength)
427 ? copyOf(array, minLength + padding)
428 : array;
429 }
430
431
432 private static long[] copyOf(long[] original, int length) {
433 long[] copy = new long[length];
434 System.arraycopy(original, 0, copy, 0, Math.min(original.length, length));
435 return copy;
436 }
437
438
439
440
441
442
443
444
445
446
447 public static String join(String separator, long... array) {
448 checkNotNull(separator);
449 if (array.length == 0) {
450 return "";
451 }
452
453
454 StringBuilder builder = new StringBuilder(array.length * 10);
455 builder.append(array[0]);
456 for (int i = 1; i < array.length; i++) {
457 builder.append(separator).append(array[i]);
458 }
459 return builder.toString();
460 }
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478 public static Comparator<long[]> lexicographicalComparator() {
479 return LexicographicalComparator.INSTANCE;
480 }
481
482 private enum LexicographicalComparator implements Comparator<long[]> {
483 INSTANCE;
484
485 @Override
486 public int compare(long[] left, long[] right) {
487 int minLength = Math.min(left.length, right.length);
488 for (int i = 0; i < minLength; i++) {
489 int result = Longs.compare(left[i], right[i]);
490 if (result != 0) {
491 return result;
492 }
493 }
494 return left.length - right.length;
495 }
496 }
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513 public static long[] toArray(Collection<? extends Number> collection) {
514 if (collection instanceof LongArrayAsList) {
515 return ((LongArrayAsList) collection).toLongArray();
516 }
517
518 Object[] boxedArray = collection.toArray();
519 int len = boxedArray.length;
520 long[] array = new long[len];
521 for (int i = 0; i < len; i++) {
522
523 array[i] = ((Number) checkNotNull(boxedArray[i])).longValue();
524 }
525 return array;
526 }
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542 public static List<Long> asList(long... backingArray) {
543 if (backingArray.length == 0) {
544 return Collections.emptyList();
545 }
546 return new LongArrayAsList(backingArray);
547 }
548
549 @GwtCompatible
550 private static class LongArrayAsList extends AbstractList<Long>
551 implements RandomAccess, Serializable {
552 final long[] array;
553 final int start;
554 final int end;
555
556 LongArrayAsList(long[] array) {
557 this(array, 0, array.length);
558 }
559
560 LongArrayAsList(long[] array, int start, int end) {
561 this.array = array;
562 this.start = start;
563 this.end = end;
564 }
565
566 @Override public int size() {
567 return end - start;
568 }
569
570 @Override public boolean isEmpty() {
571 return false;
572 }
573
574 @Override public Long get(int index) {
575 checkElementIndex(index, size());
576 return array[start + index];
577 }
578
579 @Override public boolean contains(Object target) {
580
581 return (target instanceof Long)
582 && Longs.indexOf(array, (Long) target, start, end) != -1;
583 }
584
585 @Override public int indexOf(Object target) {
586
587 if (target instanceof Long) {
588 int i = Longs.indexOf(array, (Long) target, start, end);
589 if (i >= 0) {
590 return i - start;
591 }
592 }
593 return -1;
594 }
595
596 @Override public int lastIndexOf(Object target) {
597
598 if (target instanceof Long) {
599 int i = Longs.lastIndexOf(array, (Long) target, start, end);
600 if (i >= 0) {
601 return i - start;
602 }
603 }
604 return -1;
605 }
606
607 @Override public Long set(int index, Long element) {
608 checkElementIndex(index, size());
609 long oldValue = array[start + index];
610
611 array[start + index] = checkNotNull(element);
612 return oldValue;
613 }
614
615 @Override public List<Long> subList(int fromIndex, int toIndex) {
616 int size = size();
617 checkPositionIndexes(fromIndex, toIndex, size);
618 if (fromIndex == toIndex) {
619 return Collections.emptyList();
620 }
621 return new LongArrayAsList(array, start + fromIndex, start + toIndex);
622 }
623
624 @Override public boolean equals(Object object) {
625 if (object == this) {
626 return true;
627 }
628 if (object instanceof LongArrayAsList) {
629 LongArrayAsList that = (LongArrayAsList) object;
630 int size = size();
631 if (that.size() != size) {
632 return false;
633 }
634 for (int i = 0; i < size; i++) {
635 if (array[start + i] != that.array[that.start + i]) {
636 return false;
637 }
638 }
639 return true;
640 }
641 return super.equals(object);
642 }
643
644 @Override public int hashCode() {
645 int result = 1;
646 for (int i = start; i < end; i++) {
647 result = 31 * result + Longs.hashCode(array[i]);
648 }
649 return result;
650 }
651
652 @Override public String toString() {
653 StringBuilder builder = new StringBuilder(size() * 10);
654 builder.append('[').append(array[start]);
655 for (int i = start + 1; i < end; i++) {
656 builder.append(", ").append(array[i]);
657 }
658 return builder.append(']').toString();
659 }
660
661 long[] toLongArray() {
662
663 int size = size();
664 long[] result = new long[size];
665 System.arraycopy(array, start, result, 0, size);
666 return result;
667 }
668
669 private static final long serialVersionUID = 0;
670 }
671 }